package utils;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;


public class DBConnection
{
	private static boolean state_register = false;

	public enum Encoding
	{
		UTF_8("utf8mb4");
		
		String value;
		private Encoding(String value)
		{
			this.value = value;
		}
		
		public String getValue()
		{
			return this.value;
		}
	}
	
	// MySQL 8.0 以下版本 - JDBC 驱动名及数据库 URL
    //static final String JDBC_DRIVER = "com.mysql.jdbc.Driver";  
    //static final String DB_URL = "jdbc:mysql://localhost:3306/db_name";
	
	//MySQL 8.0 以上版本 - JDBC 驱动名及数据库 URL
	//static final String JDBC_DRIVER = "com.mysql.cj.jdbc.Driver";
	//static final String DB_URL = "jdbc:mysql://localhost:3306/db_name?useSSL=false&allowPublicKeyRetrieval=true&serverTimezone=UTC";
	
	
	//MariaDB - JDBC 驱动名及数据库 URL
	static final String JDBC_DRIVER = "org.mariadb.jdbc.Driver";
	//static final String DB_URL = "jdbc:mariadb://localhost:3306/db_name?useSSL=false&allowPublicKeyRetrieval=true&serverTimezone=UTC";
	
	
	Connection connection = null;
	Statement statement = null;
	
	/**
	 * 注册数据库
	 * */
	public static void registerDriver()
	{
		DBConnection.registerDriver(DBConnection.JDBC_DRIVER);
	}
	
	/**
	 * 注册数据库
	 * */
	public static void registerDriver(String driver_class_name)
	{
		if (DBConnection.state_register)
		{
			System.err.println("Driver has been registered");
			return;
		}

		try
		{
			Class.forName(driver_class_name);
			DBConnection.state_register = true;
		}
		catch (ClassNotFoundException e)
		{
			System.out.println("驱动加载失败");
			e.printStackTrace();
		}
		
	}
	
	public DBConnection(){}
	public DBConnection(String db_url){this.init(db_url);}
	public DBConnection(String db_url, String username, String password)
	{
		this.init(db_url, username, password);
	}
	
	
	public void init(String db_url)
	{
		if (db_url == null || db_url.equals(""))
		{
			System.out.println(this.getClass().getName() + ".init:\n\tdb_url is null or equals \"\"");
			return;
		}
		
		try
		{
			this.connection = DriverManager.getConnection(db_url);
			this.statement = this.connection.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_UPDATABLE);
		}
		catch (SQLException e) {e.printStackTrace();}
		
	}
	
	public void init(String db_url, String username, String password)
	{
		if (db_url == null || db_url.equals(""))
		{
			System.out.println(this.getClass().getName() + ".init:\n\tat least one argument is null or equals \"\"");
			return;
		}
		
		try
		{
			this.connection = DriverManager.getConnection(db_url, username, password);
			this.statement = this.connection.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_UPDATABLE);
		}
		catch (SQLException e) {e.printStackTrace();}
	}
	
	
	public void init(String host, String port, String database_name, String username, String password)
	{
		this.init("mariadb", host, port, database_name, username, password);
	}
	
	
	public void init(String sub_protocol, String host, String port, String database_name, String username, String password)
	{
		this.init(DBConnection.getDB_URL(sub_protocol, host, port, database_name), username, password);
	}
	
	
	public static String getDB_URL(String host, String port, String database_name)
	{
		return DBConnection.getDB_URL("mariadb", host, port, database_name);
	}
	
	public static String getDB_URL(String sub_protocol, String host, String port, String database_name)
	{
		if (sub_protocol == null || sub_protocol.equals("")
			||host == null || host.equals("")
			|| port == null || port.equals("")
			|| database_name == null || database_name.equals(""))
		{
			System.out.println(DBConnection.class.getName() + ".getDB_URL:\n\tat least one argument is null or equals \"\"");
			return null;
		}
		return "jdbc:" + sub_protocol + "://" + host + ":" + port + "/" + database_name + "?useSSL=false";
	}
	
	
	@Override
	protected void finalize()
			throws Throwable
	{
		super.finalize();
		this.close();
	}

	public void close()
	{
		try
		{
			if (this.statement != null)
				this.statement.close();
			if (this.connection != null)
				this.connection.close();
		}
		catch (SQLException e) {e.printStackTrace();}
	}
	
	
	public void setTableEncoding(DBConnection.Encoding encoding)
	{
		String sql = "";
		try
		{
			this.statement.execute(sql);
		}
		catch (SQLException e) {e.printStackTrace();}
	}
	
	
	public void setDBEncoding(DBConnection.Encoding encoding)
	{
		String sql = "";
		try
		{
			this.statement.execute(sql);
		}
		catch (SQLException e) {e.printStackTrace();}
	}
	
	
	
	/**
	 * 注意手动close()
	 * */
	public final ResultSet getResultSet(String sql)
	{
		try
		{
			return this.statement.executeQuery(sql);
		}
		catch (SQLException e) {e.printStackTrace();}
		return null;
	}
	
	
	/**
	 * @return 数据库statement
	 * */
	public final Statement getStatement()
	{
		return this.statement;
	}
	
	
	public final PreparedStatement getPreparedStatement(String sql)
	{
		try
		{
			return this.connection.prepareStatement(sql);
		}
		catch (SQLException e) {e.printStackTrace();}
		return null;
	}
}





